unit FolderView;

interface

uses
  SysUtils, Classes, Controls, ComCtrls,Dialogs,FolderFile,windows,ShellAPI,Utils;

type
  TSpecialFolder =(sfNormal,sfDiskList);
  TFolderView = class(TListView)
  private
    FCurrDir : String;
    FFolderList: TFolderList;
    procedure SetFolderList(const Value: TFolderList);
    procedure FindAll(const Path: String);
    procedure ListDrives;
    procedure FillView;

    { Private declarations }
  protected
    { Protected declarations }
  public
    procedure FillDir(FilePath : String);
    procedure Fill(sf : TSpecialFolder);
    procedure ForceAtLastOneSelected;
  public
    { Public declarations }
    constructor Create(Owner:TComponent);override;
    destructor Destroy ;override ;
  published
    { Published declarations }
  end;

procedure Register;

implementation




procedure Register;
begin
  //RegisterComponents('Samples', [TFolderView]);
end;

{ TFolderView }

constructor TFolderView.Create(Owner: TComponent);
begin
  inherited;
  //Width := Width div 2 ;
  ViewStyle := vsReport;
  RowSelect := True ;
  with Columns.Add do begin
     Caption := 'FileName';
     Width := 100;
  end;
  Columns.Add.Caption := 'Ext';
  Columns.Add.Caption := 'IsDir';
  Columns.Add.Caption := 'Size';
  with Columns.Add do begin
    Caption := 'Datetime';
    Width := 150;
  end;
  FFolderList := TFolderList.Create;
  
end;
procedure TFolderView.FindAll (const Path: String) ;
var
   Res: TSearchRec;
   EOFound: Boolean;
   Folder : TFolder ;
begin
   EOFound:= False;
   FFolderList.Clear ;
   if FindFirst(Path+'*.*', faAnyFile, Res) = 0 then
     while  not EOFound do begin
       if (Res.Name <>'.') and (res.Name <>'..') then  begin
         Folder := TFolder.Create ;
         Folder.Name := res.Name;
         Folder.Size := Res.Size ;
         Folder.IsFile := not (Res.Attr and faDirectory = faDirectory);
         Folder.Date := FileDateToDateTime(res.Time);
         FFolderList.Add(Folder);
       end;
       EOFound:= FindNext(Res) <> 0;
     end;
   FindClose(Res.FindHandle);
end;
destructor TFolderView.Destroy;
begin
  FFolderList.Free ;
  inherited;
end;
procedure TFolderview.FillView;
var i : Integer;
begin
   Items.Clear ;
   for i := 0 to FFolderList.Count -1 do
   begin
     with Items.add do
     begin
       Data :=  FFolderList.GetItem(i) ;
       Caption :=  FFolderList.GetItem(i).FileName;
       SubItems.Add(FFolderList.GetItem(i).FileExt);
       SubItems.Add(FFolderList.GetItem(i).FileType);
       SubItems.Add(FFolderList.GetItem(i).SizeStr);
       SubItems.Add(FFolderList.GetItem(i).DateStr);
     end;
   end;
   ForceAtLastOneSelected
end;  
procedure TFolderView.FillDir(FilePath: String);
var
   i :Integer ;
begin
   LockWindowUpdate(Handle);
   FCurrDir := EnsureBackSlash(FilePath) ;
   FindAll(FCurrDir);
   FillView;
   LockWindowUpdate(0);
end;

procedure TFolderView.SetFolderList(const Value: TFolderList);
begin
  FFolderList := Value;
end;


// delphi GetLogicalDriveStrings by google 
procedure TFolderView.ListDrives;
const
  DRIVE_UNKNOWN = 0;
  DRIVE_NO_ROOT_DIR = 1;
  DRIVE_REMOVABLE = 2;
  DRIVE_FIXED = 3;
  DRIVE_REMOTE = 4;
  DRIVE_CDROM = 5;
  DRIVE_RAMDISK = 6;
var
  r: LongWord;
  Drives: array[0..128] of char;
  pDrive: PChar;
  Folder : TFolder ;
begin
  FFolderList.clear ;
  r := GetLogicalDriveStrings(SizeOf(Drives), Drives);
  if r = 0 then Exit;
  if r > SizeOf(Drives) then
    raise Exception.Create(SysErrorMessage(ERROR_OUTOFMEMORY));
  pDrive := Drives;
  while pDrive^ <> #0 do
  begin
    //if GetDriveType(pDrive) = DRIVE_FIXED then
    //  Form1.ComboBox1.Items.Add(pDrive);
    Folder := TFolder.Create;
    Folder.IsFile := false;
    Folder.Name := pDrive;
    FFolderList.Add(Folder);
    Inc(pDrive, 4);
  end;
end;

procedure TFolderView.Fill(sf: TSpecialFolder);
begin
  if sf = sfDiskList then
  begin
    ListDrives;
    FillView;
  end;
end;

procedure TFolderView.ForceAtLastOneSelected;
begin
  if (Selcount =0 ) and (items.Count > 0 ) then begin
    Selected := Items[0];
    ItemFocused:= Items[0];
  end;

end;

end.
